{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# hex adapter demo\n",
    "\n",
    "*<<< check out other demo models [here](https://github.com/FullControlXYZ/fullcontrol/tree/master/models/README.md) >>>*\n",
    "  \n",
    "run all cells in this notebook, or press shift+enter to run each cell sequentially \n",
    "\n",
    "if you change one of the code cells, make sure you run it and all subsequent cells again (in order)\n",
    "\n",
    "*this document is a jupyter notebook - if they're new to you, check out how they work: [link](https://www.google.com/search?q=ipynb+tutorial), [link](https://jupyter.org/try-jupyter/retro/notebooks/?path=notebooks/Intro.ipynb), [link](https://colab.research.google.com/)*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import fullcontrol as fc\n",
    "import lab.fullcontrol as fclab\n",
    "from math import cos, sin, tau, pi, atan, sqrt, acos, radians\n",
    "from copy import deepcopy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "output = 'visualize'  # 'visualize' or 'gcode'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# design parameters\n",
    "\n",
    "lattice_id = 'M1'\n",
    "# Lattice Type (www.tinyurl.com/lattice-research) - Lattice structure sub-family, as identified in the journal paper investigating these structures (www.tinyurl.com/lattice_paper)\n",
    "# default value: M1 ; options: 'M1', 'M2', 'M3', 'M4'\n",
    "\n",
    "alpha = 30\n",
    "# Star-Polygon Angle (Degrees) - Angle of star-polygon corners\n",
    "# default value: 30 ; guideline range: 15 to 150\n",
    "\n",
    "seg_length = 4.33\n",
    "# Strut Length (mm) - Length of each lattice strut\n",
    "# default value: 4.33 ; guideline range: 1 to 50\n",
    "\n",
    "units_x = 10\n",
    "# Length (Unit Cells) - Number of units cells along the length of the lattice\n",
    "# default value: 10 ; guideline range: 4 to 15\n",
    "\n",
    "units_y = 3\n",
    "# Width (Unit Cells) - Number of units cells in the width direction - the actual value may be more than this to ensure neat printing between layers\n",
    "# default value: 3 ; guideline range: 1 to 5\n",
    "\n",
    "EW = 0.5\n",
    "# Extrusion Width (mm) - Width of printed lines (i.e. width of each lattice strut) - recommended value: 1-1.5x nozzle diameter\n",
    "# default value: 0.5 ; guideline range: 0 to 100\n",
    "\n",
    "EH = 0.2\n",
    "# Extrusion Height (mm) - Height of printed lines (i.e. layer thickness) - recommended value: 0.25-0.5x nozzle diameter\n",
    "# default value: 0.2 ; guideline range: 0.01 to 5\n",
    "\n",
    "layers = 2\n",
    "# Layers -\n",
    "# default value: 2 ; guideline range: 1 to 5\n",
    "\n",
    "start_x = 30\n",
    "# X Start (mm) - Approximate start-point of lattice in X\n",
    "# default value: 30 ; guideline range: -1000000 to 1000000\n",
    "\n",
    "start_y = 30\n",
    "# Y Start (mm) - Approximate start-point of lattice in Y\n",
    "# default value: 30 ; guideline range: -1000000 to 1000000\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# generate the design (make sure you've run the above cells before running this cell)\n",
    "\n",
    "layers = int(layers)\n",
    "\n",
    "rows = units_y \n",
    "\n",
    "if lattice_id == 'M1':\n",
    "    steplist_repeating_unit = []\n",
    "    # define the repeating unit (set of lines = Points)\n",
    "    steplist_repeating_unit.append(fc.Point(x=0, y=0, z=0))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(-alpha/2)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(-60+alpha/2)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(120-alpha/2)))\n",
    "\n",
    "    # calculate offsets for repeating the repeating unit\n",
    "    repeat_offset_x = steplist_repeating_unit[3].x # offset for repeating in x along a line\n",
    "    row_offset_x = -(steplist_repeating_unit[2].x-steplist_repeating_unit[1].x)  # offset in x for every other row\n",
    "    row_offset_y = -(steplist_repeating_unit[1].y+steplist_repeating_unit[2].y) # offset in y between rows\n",
    "\n",
    "    # repeat unit to make a full row, printing to the end and back\n",
    "    steplist_row_1 = fc.move(steplist_repeating_unit, fc.Vector(x=repeat_offset_x), copy=True, copy_quantity=units_x)\n",
    "    steplist_row_2 = fclab.reflectXYpolar_list(steplist_row_1, fc.Point(x=0,y=0), 0)\n",
    "\n",
    "    # repeat the row, with a constant offset in y and alternating offset in x\n",
    "    steplist_lattice = []\n",
    "    rows = (units_y*2)-1\n",
    "    for i in range(rows):\n",
    "        x_offset_now = row_offset_x if i%2 == 1 else 0 \n",
    "        steplist_lattice.extend(fc.move(steplist_row_1+steplist_row_2, fc.Vector(x=x_offset_now, y=row_offset_y*i)))\n",
    "\n",
    "elif lattice_id == 'M2':\n",
    "    dev_angle = (atan((1-cos(radians(alpha)))/(sqrt(3)+sin(radians(alpha))))*180/pi)\n",
    "\n",
    "    steplist_repeating_unit = []\n",
    "    # define the repeating unit for row 1 (set of lines = Points)\n",
    "    steplist_repeating_unit.append(fc.Point(x=0, y=0, z=0))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle+90-alpha)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle+30)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle-150-alpha)))\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2], seg_length, radians(dev_angle+30-alpha)))  # travel line 4#\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle-150)))  # travel line 5#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2], seg_length, radians(dev_angle-90)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle-30)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle+30)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle+90)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle+150)))\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2], seg_length, radians(dev_angle-30)))  # travel line 11#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2], seg_length, radians(dev_angle+150-alpha)))\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2], seg_length, radians(dev_angle-30-alpha)))  # travel line 13#\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1], seg_length, radians(dev_angle-90)))  # travel line 14#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))\n",
    "\n",
    "    # calculate offsets for repeating the repeating unit\n",
    "    repeat_offset_x = steplist_repeating_unit[19].x\n",
    "    row_offset_x = (steplist_repeating_unit[16].x-steplist_repeating_unit[8].x)\n",
    "    row_offset_y = (steplist_repeating_unit[3].y-steplist_repeating_unit[9].y)\n",
    "\n",
    "    # repeat unit to make row 1\n",
    "    steplist_row_1 = fc.move(steplist_repeating_unit, fc.Vector(x=repeat_offset_x), copy=True, copy_quantity=units_x)\n",
    "\n",
    "    # Start row 2\n",
    "    steplist_repeating_unit_back = []\n",
    "    steplist_repeating_unit_back_start_x = steplist_repeating_unit[1].x+(units_x*repeat_offset_x)+row_offset_x\n",
    "    steplist_repeating_unit_back_start_y = steplist_repeating_unit[1].y+row_offset_y\n",
    "\n",
    "    # define the repeating unit for row 2(set of lines = Points)\n",
    "    steplist_repeating_unit_back.append(fc.Point(x=steplist_repeating_unit_back_start_x, y=steplist_repeating_unit_back_start_y))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle-90-alpha)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle+90)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle+150-alpha)))\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2], seg_length, radians(dev_angle-30-alpha)))  # travel line 4#\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2], seg_length, radians(dev_angle+150)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle-150-alpha)))\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2], seg_length, radians(dev_angle+30-alpha)))  # travel line 7#\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2], seg_length, radians(dev_angle-150)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle-90)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle-30)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle+30)))\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2], seg_length, radians(dev_angle+90)))  # travel line 12#\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle+150)))  # travel line 13#\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1], seg_length, radians(dev_angle-150)))  # travel line 14#\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "\n",
    "    # repeat unit to make row 2\n",
    "    steplist_row_2 = fc.move(steplist_repeating_unit_back, fc.Vector(x=-repeat_offset_x), copy=True, copy_quantity=units_x)\n",
    "    steplist_lattice = fc.move(steplist_row_1+steplist_row_2, fc.Vector(y=2*row_offset_y), copy=True, copy_quantity=units_y)\n",
    "\n",
    "elif lattice_id == 'M3':\n",
    "    steplist_repeating_unit = []\n",
    "    # define the repeating unit for row 1 (set of lines = Points)\n",
    "    steplist_repeating_unit.append(fc.Point(x=0, y=0, z=0))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(120)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(0)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(180-alpha)))    #highest: end point of strut 3\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(-alpha)))      #travel line 4#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(-120)))     \n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(60-alpha)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(-120)))       #lowest: end point of strut 7\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(0)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(120)))\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(-60)))     #travel line 10#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))       \n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(120-alpha)))  \n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(-60)))     #travel line 12#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))\n",
    "\n",
    "    rotation_angle = -atan((steplist_repeating_unit[15].y-steplist_repeating_unit[1].y)/(steplist_repeating_unit[15].x-steplist_repeating_unit[1].x))\n",
    "    steplist_repeating_unit = fc.move_polar(steplist_repeating_unit, steplist_repeating_unit[1], 0, rotation_angle)\n",
    "\n",
    "    # calculate offsets for repeating the repeating unit\n",
    "    repeat_offset_x = (steplist_repeating_unit[17].x-steplist_repeating_unit[0].x)\n",
    "    row_offset_y = (steplist_repeating_unit[3].y-steplist_repeating_unit[9].y)\n",
    "    steplist_repeating_unit_back_start_x = (steplist_repeating_unit[3].x-steplist_repeating_unit[9].x) + (units_x+1)*repeat_offset_x\n",
    "\n",
    "    # repeat unit to make row 1\n",
    "    steplist_row_1 = fc.move(steplist_repeating_unit, fc.Vector(x=repeat_offset_x), copy=True, copy_quantity=units_x)\n",
    "\n",
    "    steplist_repeating_unit_back = []\n",
    "    steplist_repeating_unit_back.append(steplist_repeating_unit[0])\n",
    "    steplist_repeating_unit_back.append(steplist_repeating_unit[2])\n",
    "    steplist_repeating_unit_back.append(steplist_repeating_unit[3])\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(steplist_repeating_unit[2])\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit_back.append(steplist_repeating_unit[1])\n",
    "    steplist_repeating_unit_back.append(steplist_repeating_unit[0])\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(steplist_repeating_unit[1])\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit_back.append(fc.move(steplist_repeating_unit[10], fc.Vector(x=-repeat_offset_x)))\n",
    "    steplist_repeating_unit_back.append(fc.move(steplist_repeating_unit[11], fc.Vector(x=-repeat_offset_x)))\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(fc.move(steplist_repeating_unit[10], fc.Vector(x=-repeat_offset_x)))\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit_back.append(fc.move(steplist_repeating_unit[9], fc.Vector(x=-repeat_offset_x)))\n",
    "    steplist_repeating_unit_back.append(fc.move(steplist_repeating_unit[8], fc.Vector(x=-repeat_offset_x)))\n",
    "    steplist_repeating_unit_back.append(fc.move(steplist_repeating_unit[0], fc.Vector(x=-repeat_offset_x)))\n",
    "    steplist_repeating_unit_back = fc.move(steplist_repeating_unit_back,fc.Vector(x=steplist_repeating_unit_back_start_x,y=row_offset_y))\n",
    "\n",
    "    # repeat unit to make row 2\n",
    "    steplist_row_2 = fc.move(steplist_repeating_unit_back, fc.Vector(x=-repeat_offset_x), copy=True, copy_quantity=units_x+1)\n",
    "    steplist_lattice = fc.move(steplist_row_1+steplist_row_2, fc.Vector(y=2*row_offset_y), copy=True, copy_quantity=units_y)\n",
    "\n",
    "elif lattice_id == 'M4':\n",
    "    if alpha == 150: alpha=120 # fixes issue with alpha > 135\n",
    "    dev_angle =  abs(acos((-sqrt(1+sin(2*radians(alpha))))/((sqrt(3-2*cos(radians(alpha))+2*sin(radians(alpha))))))*180/pi)\n",
    "\n",
    "    steplist_repeating_unit = []\n",
    "    # define the repeating unit for row 1 (set of lines = Points)\n",
    "    steplist_repeating_unit.append(fc.Point(x=0, y=0, z=0))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(90-dev_angle)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(270-dev_angle-alpha)))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(180-dev_angle)))    #highest: end point of strut 3\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(-dev_angle)))      #travel line 4#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(180-dev_angle-alpha)))     \n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(90-dev_angle-alpha)))   #lowest: end point of strut 6\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(-dev_angle-alpha)))\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-2],seg_length,radians(-90-dev_angle-alpha)))  #travel line 8#\n",
    "    steplist_repeating_unit.append(fc.polar_to_point(steplist_repeating_unit[-1],seg_length,radians(-180-dev_angle-alpha))) #travel line 9#\n",
    "    steplist_repeating_unit.append(fc.Extruder(on=True))\n",
    "\n",
    "    # calculate offsets for repeating the repeating unit\n",
    "    repeat_offset_x = (steplist_repeating_unit[12].x-steplist_repeating_unit[0].x) # offset for repeating in x along a line\n",
    "    row_offset_y = (steplist_repeating_unit[3].y-steplist_repeating_unit[8].y) # offset in y between rows (end of line 3 - end of line 7)\n",
    "\n",
    "    # repeat unit to make row 1\n",
    "    steplist_row_1 = fc.move(steplist_repeating_unit, fc.Vector(x=repeat_offset_x), copy=True, copy_quantity=units_x)\n",
    "\n",
    "    steplist_repeating_unit_back = []\n",
    "    steplist_repeating_unit_back_start_x = steplist_row_1[-2].x+(steplist_repeating_unit[1].x-steplist_repeating_unit[0].x)\n",
    "    steplist_repeating_unit_back_start_y = row_offset_y-(steplist_repeating_unit[7].y-steplist_repeating_unit[8].y-(steplist_repeating_unit[5].y-steplist_repeating_unit[7].y))\n",
    "    # define the repeating unit for row 2(set of lines = Points)\n",
    "    steplist_repeating_unit_back.append(fc.Point(x=steplist_repeating_unit_back_start_x, y=steplist_repeating_unit_back_start_y))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1],seg_length,radians(-90-dev_angle)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1],seg_length,radians(90-dev_angle-alpha)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1],seg_length,radians(-dev_angle-alpha)))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1],seg_length,radians(-90-dev_angle-alpha))) \n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1],seg_length,radians(180-dev_angle)))\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2],seg_length,radians(-dev_angle)))   #travel line 6#\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2],seg_length,radians(180-dev_angle-alpha)))\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=False))\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-2],seg_length,radians(90-dev_angle-alpha)))    #travel line 8#\n",
    "    steplist_repeating_unit_back.append(fc.polar_to_point(steplist_repeating_unit_back[-1],seg_length,radians(-dev_angle-alpha)))  #travel line 9#\n",
    "    steplist_repeating_unit_back.append(fc.Extruder(on=True))\n",
    "\n",
    "    steplist_row_2 = fc.move(steplist_repeating_unit_back, fc.Vector(x=-repeat_offset_x), copy=True, copy_quantity=units_x)\n",
    "\n",
    "    if units_y%2 != 0: units_y += 1\n",
    "    row_pairs = int(units_y/2)\n",
    "    steplist_lattice = fc.move(steplist_row_1+steplist_row_2, fc.Vector(y=2*row_offset_y), copy=True, copy_quantity=row_pairs)\n",
    "\n",
    "# add three sacrificial printed lines to return to start point neatly, ready to being the next layer under steady-state conditions\n",
    "steplist_lattice.extend([fc.Point(x=-repeat_offset_x),fc.Point(y=0),fc.Point(x=0)])\n",
    "\n",
    "if output == 'visualize':\n",
    "    # the visual preview becomes very slow when there are lots of lines. Remove travel to make it show more quickly\n",
    "    steplist_lattice = fc.points_only(steplist_lattice)\n",
    "\n",
    "# make lots of layers\n",
    "steplist_multilayer = fc.move(steplist_lattice, fc.Vector(z=EH), copy=True, copy_quantity=layers)\n",
    "\n",
    "\n",
    "# offset the whole procedure. z dictates the gap between the nozzle and the bed for the first layer, assuming the model was designed with a first layer z-position of 0\n",
    "model_offset = fc.Vector(x=start_x, y=start_y, z=0.8*EH)\n",
    "\n",
    "steps = fc.move(steplist_multilayer, model_offset) # all layers - comment out this or the previous line"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create annotations (these can also be produced during loops in the cell that creates the design)\n",
    "\n",
    "annotation_pts = []\n",
    "annotation_pts.append(fc.Point(x=start_x-seg_length*5, y=start_y+seg_length*5, z=0))\n",
    "annotation_pts.append(fc.Point(x=start_x, y=start_y, z=0))\n",
    "annotation_pts.append(fc.Point(x=start_x+seg_length*5, y=start_y-seg_length*5, z=0))\n",
    "annotation_labels = [\"Lattices used in a research article\", \"Use TPU or similar ductile polymers\", \"More details: www.tinyurl.com/lattice-research\"]\n",
    "\n",
    "# update annotations from legacy to new format\n",
    "for i in range(len(annotation_pts)):\n",
    "    steps.append(fc.PlotAnnotation(point=annotation_pts[i], label=annotation_labels[i]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# add initial settings for primer\n",
    "\n",
    "initial_print_speed = 1000\n",
    "initial_EW = EW\n",
    "initial_EH = EH\n",
    "primer = 'front_lines_then_y'\n",
    "\n",
    "# the following parameters are over-written by user selections in the webapp:\n",
    "# generic / ultimaker2plus / prusa_i3 / ender_3 / cr_10 / bambulab_x1 / toolchanger_T0\n",
    "printer_name = 'ultimaker2plus'\n",
    "nozzle_temp = 210\n",
    "bed_temp = 40\n",
    "fan_percent = 100\n",
    "material_flow_percent = 100\n",
    "print_speed_percent = 100\n",
    "\n",
    "# fc printer_params\n",
    "\n",
    "gcode_controls = fc.GcodeControls(\n",
    "    printer_name=printer_name,\n",
    "    initialization_data={\n",
    "        'primer': primer,\n",
    "        'print_speed': initial_print_speed,\n",
    "        'nozzle_temp': nozzle_temp,\n",
    "        'bed_temp': bed_temp,\n",
    "        'fan_percent': fan_percent,\n",
    "        'material_flow_percent': material_flow_percent,\n",
    "        'print_speed_percent': print_speed_percent,\n",
    "        'extrusion_width': initial_EW,\n",
    "        'extrusion_height': initial_EH})\n",
    "\n",
    "plot_controls = fc.PlotControls(\n",
    "    style='tube',\n",
    "    initialization_data={\n",
    "        'extrusion_width': initial_EW,\n",
    "        'extrusion_height': initial_EH})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design_name = 'star_polygon_lattice'\n",
    "\n",
    "gcode_controls.save_as = design_name\n",
    "fc.transform(steps, 'gcode', gcode_controls) if output == 'gcode' else fc.transform(steps, 'plot', plot_controls)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### please tell us what you're doing with FullControl!\n",
    "\n",
    "- tag FullControlXYZ on social media ([twitter](https://twitter.com/FullControlXYZ), [instagram](https://www.instagram.com/fullcontrolxyz/), [linkedin](https://www.linkedin.com/in/andrew-gleadall-068587119/), [tiktok](https://www.tiktok.com/@fullcontrolxyz))\n",
    "- email [info@fullcontrol.xyz](mailto:info@fullcontrol.xyz)\n",
    "- post on the [subreddit](https://reddit.com/r/fullcontrol)\n",
    "- post in the [github discussions or issues tabs](https://github.com/FullControlXYZ/fullcontrol/issues)\n",
    "\n",
    "in publications, please cite the original FullControl paper and the github repo for the new python version:\n",
    "\n",
    "- Gleadall, A. (2021). FullControl GCode Designer: open-source software for unconstrained design in additive manufacturing. Additive Manufacturing, 46, 102109. \n",
    "- Gleadall, A. and Leas, D. (2023). FullControl [electronic resource: python source code]. available at: https://github.com/FullControlXYZ/fullcontrol"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.3"
  },
  "vscode": {
   "interpreter": {
    "hash": "2b13a99eb0d91dd901c683fa32c6210ac0c6779bab056ce7c570b3b366dfe237"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
